package com.ruoyi.system.service.impl;

import java.util.List;
import java.util.ArrayList;
import java.io.File;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.utils.file.FileUploadUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.system.mapper.DocMapper;
import com.ruoyi.system.domain.Doc;
import com.ruoyi.system.service.IDocService;

import static com.ruoyi.common.utils.SecurityUtils.getUsername;

/**
 * 文档Service业务层处理
 * 
 * @author tq
 * @date 2025-04-19
 */
@Service
public class DocServiceImpl implements IDocService 
{
    @Autowired
    private DocMapper docMapper;

    /**
     * 查询文档
     * 
     * @param docId 文档主键
     * @return 文档
     */
    @Override
    public Doc selectDocByDocId(Long docId)
    {
        return docMapper.selectDocByDocId(docId);
    }

    /**
     * 查询文档列表
     * 
     * @param doc 文档
     * @return 文档
     */
    @Override
    public List<Doc> selectDocList(Doc doc)
    {
        return docMapper.selectDocList(doc);
    }

    /**
     * 新增文档
     * 
     * @param doc 文档
     * @return 结果
     */
    @Override
    public int insertDoc(Doc doc)
    {
        doc.setCreateTime(DateUtils.getNowDate());
        doc.setCreateBy(getUsername());
        return docMapper.insertDoc(doc);
    }

    /**
     * 修改文档
     * 
     * @param doc 文档
     * @return 结果
     */
    @Override
    public int updateDoc(Doc doc)
    {
        doc.setUpdateTime(DateUtils.getNowDate());
        doc.setUpdateBy(getUsername());
        return docMapper.updateDoc(doc);
    }

    /**
     * 批量删除文档
     * 
     * @param docIds 需要删除的文档主键
     * @return 结果
     */
    @Override
    public int deleteDocByDocIds(Long[] docIds)
    {
        return docMapper.deleteDocByDocIds(docIds);
    }

    /**
     * 删除文档信息
     * 
     * @param docId 文档主键
     * @return 结果
     */
    @Override
    public int deleteDocByDocId(Long docId)
    {
        return docMapper.deleteDocByDocId(docId);
    }

    @Override
    public List<Doc> selectDocByUnitIds(Long[] unitIds) {
        return docMapper.selectDocByUnitIds(unitIds);
    }

    @Override
    public List<Doc> selectDocByTypeIds(Long[] typeIds) {
        return docMapper.selectDocByTypeIds(typeIds);
    }

    /**
     * 批量上传PDF文档
     * 
     * @param files 文件数组
     * @param typeId 组卷类别ID
     * @param unitId 管理单位ID
     * @param loc 文档位置
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class) // 使用默认事务超时，保证稳定性
    public int batchUploadDocs(MultipartFile[] files, Long typeId, Long unitId, String loc) {
        if (files == null || files.length == 0) {
            throw new RuntimeException("请选择要上传的文件！");
        }

        int successCount = 0;
        List<String> uploadedFiles = new ArrayList<>();
        List<Doc> docList = new ArrayList<>();
        
        try {
            long startTime = System.currentTimeMillis();
            System.out.println("开始批量上传处理，文件数量: " + files.length);
            
            // 预先创建公共数据，避免重复计算
            String currentUser = getUsername();
            java.util.Date currentTime = DateUtils.getNowDate();
            String locationValue = StringUtils.isNotEmpty(loc) ? loc : "";
            String uploadBasePath = RuoYiConfig.getUploadPath();
            
            // 预分配集合容量，避免动态扩容
            docList = new ArrayList<>(files.length);
            uploadedFiles = new ArrayList<>(files.length);
            
            // 批量验证文件，快速失败
            for (MultipartFile file : files) {
                if (file.isEmpty()) {
                    continue;
                }
                
                String fileName = file.getOriginalFilename();
                if (!fileName.toLowerCase().endsWith(".pdf")) {
                    throw new RuntimeException("文件 " + fileName + " 不是PDF格式！");
                }
                
                if (file.getSize() > 100 * 1024 * 1024*50) { // 500MB
                    throw new RuntimeException("文件 " + fileName + " 超出大小限制（500MB）！");
                }
            }
            
            // 简化日志输出，减少性能影响
            
            // 批量处理文件上传和数据准备
            for (MultipartFile file : files) {
                if (file.isEmpty()) {
                    continue;
                }
                
                String fileName = file.getOriginalFilename();
                
                // 上传文件
                String uploadPath = FileUploadUtils.upload(uploadBasePath, file);
                uploadedFiles.add(uploadPath);
                
                // 创建文档记录
                Doc doc = new Doc();
                doc.setTypeId(typeId);
                doc.setUnitId(unitId);
                doc.setDocType("1"); // PDF型
                doc.setLoc(locationValue);
                doc.setUrl(uploadPath);
                doc.setName(fileName.substring(0, fileName.lastIndexOf(".")));
                doc.setCreateTime(currentTime);
                doc.setCreateBy(currentUser);
                doc.setDelFlag("0");
                
                docList.add(doc);
            }
            
            // 文件上传完成
            long uploadEndTime = System.currentTimeMillis();
            System.out.println("文件上传阶段完成，耗时: " + (uploadEndTime - startTime) + "ms");
            
            // 直接批量插入，不再分批（20个文件以内直接插入更快）
            if (docList.size() > 0) {
                long dbStartTime = System.currentTimeMillis();
                int result = docMapper.batchInsertDoc(docList);
                long dbEndTime = System.currentTimeMillis();
                System.out.println("数据库插入完成，耗时: " + (dbEndTime - dbStartTime) + "ms");
                successCount = result;
            }
            
            // 输出总体性能数据
            long totalTime = System.currentTimeMillis();
            System.out.println("批量上传完成: " + files.length + "个文件, 总耗时: " + (totalTime - startTime) + "ms");
            
            return successCount;
            
        } catch (Exception e) {
            // 如果出现异常，删除已上传的文件
            for (String uploadPath : uploadedFiles) {
                try {
                    String filePath = RuoYiConfig.getUploadPath() + uploadPath;
                    File fileToDelete = new File(filePath);
                    if (fileToDelete.exists()) {
                        fileToDelete.delete();
                    }
                } catch (Exception deleteEx) {
                    // 删除文件失败，记录日志但不影响主流程
                    System.err.println("删除文件失败: " + uploadPath);
                }
            }
            throw new RuntimeException("批量上传失败: " + e.getMessage());
        }
    }
}
